package Chapter2;

public class PolySinglyList<T extends Comparable<? super T> & Addible<? super T>> extends SortedSinglyList<T> {

    public PolySinglyList(boolean asc) {
        super(asc);
    }

    public PolySinglyList() {
        this(true);
    }

    public PolySinglyList(T[] terms, boolean asc) {
        super(terms, asc);
    }

    public PolySinglyList(PolySinglyList list) {
        super(list);
    }

    public String toString() {
        String str = this.getClass().getName() + ":";
        for (Node<T> p = this.head.next; p != null; p = p.next)
            str += p.data.toString();
        return str;
    }

    /**
     * 多项式相加，this+=list，不改变list。this、list的升降序必须一致
     *
     * @param list
     */
    public void addAll(PolySinglyList<T> list) {
        if (this.asc != list.asc)
            throw new java.lang.IllegalArgumentException("两条链表的升降序不一致！");
        Node<T> front = this.head, p = front.next; //front是p的前驱结点
        Node<T> q = list.head.next;
        while (p != null && q != null) {
            if (p.data.compareTo(q.data) == 0) {   //两项可以相加
                p.data.add(q.data);
                if (p.data.removable())
                    front.next = p.next;
                else
                    front = front.next;
                p = front.next;
                q = q.next;
            } else {
                if (asc ? p.data.compareTo(q.data) > 0 : p.data.compareTo(q.data) < 0) {
                    front.next = new Node<T>(q.data, p); //复制q结点并插入到front结点之后、p结点之前
                    q = q.next;
                } else {
                    p = p.next;
                    front = front.next;
                }
            }
            while (q != null) {
                front.next = new Node<T>(q.data, null);
                front = front.next;
                q = q.next;
            }
        }

    }

    /**
     * 加法，并集 返回this+list的多项式，不改变this和list
     *
     * @param list
     * @return PolySinglyList<T></T>
     */
    public PolySinglyList<T> union(PolySinglyList<T> list, boolean add) {
        if (this.asc != list.asc)
            throw new java.lang.IllegalArgumentException("两条链表的升降序不一致！");
        PolySinglyList<T> poly = new PolySinglyList<T>();
        Node<T> rear = poly.head;
        Node<T> p = this.head.next;
        Node<T> q = list.head.next;
        while (p != null && q != null) {
            if (p.data.compareTo(q.data) == 0) {
                T obj = p.data;
                if (add)
                    obj.add(q.data);
                else
                    obj.minus(q.data);
                if (!obj.removable()) {
                    rear.next = new Node<T>(obj, null);
                    rear = rear.next;
                }
                p = p.next;
                q = q.next;
            } else if (p.data.compareTo(q.data) < 0) {  //p的指数较小
                rear.next = new Node<T>(p.data, null);//复制p结点并插入到rear结点之后
                rear = rear.next;
                p = p.next;
            } else {
                if (add)
                    rear.next = new Node<T>(q.data, null);//复制q结点并插入到rear结点之后
                else {

                    rear.next = new Node<T>(q.data, null);
                }
                rear = rear.next;
                q = q.next;
            }
        }
        while (q != null) {
            if (add)
                rear.next = new Node<T>(q.data, null);
            else
                rear.next = new Node<T>(q.data, null);
            rear = rear.next;
            q = q.next;
        }

        while (p != null) {        //将p结点及之后的剩余结点复制并插入到poly链表尾
            rear.next = new Node<T>(p.data, null);
            rear = rear.next;
            p = p.next;
        }


       /*PolySinglyList<TermX> poly = new PolySinglyList<TermX>(this.asc);
        Node<TermX> rear = poly.head;
        Node<TermX> p = (Node<TermX>) this.head.next;
        Node<TermX> q = (Node<TermX>) list.head.next;

        while (p != null && q != null) {
            if (p.data.compareTo(q.data) == 0) {
                if (add)
                   rear.next = new Node<TermX>(new TermX(p.data.coef+q.data.coef, p.data.xexp), null);

                    //poly.insert(new TermX(p.data.getCoef()+q.data.getCoef(),p.data.getXexp()));
                else
                    rear.next = new Node<TermX>(new TermX(p.data.coef-q.data.coef, p.data.xexp), null);
                if (rear.next.data.removable()) {
                    rear.next = null;
                    p = p.next;
                    q = q.next;
                }
                rear = rear.next;
                p = p.next;
                q = q.next;
            } else if (p.data.compareTo(q.data) < 0) {
                rear.next = new Node<TermX>(new TermX(p.data.coef, p.data.xexp), null);
                rear = rear.next;
                p = p.next;
            } else {
                if (add)
                    rear.next = new Node<TermX>(new TermX(q.data.coef, q.data.xexp), null);
                else
                    rear.next = new Node<TermX>(new TermX(-q.data.coef, q.data.xexp), null);
                rear = rear.next;
                q = q.next;
            }
        }

        while (p != null) {
            rear.next = new Node<TermX>(new TermX(p.data.coef, p.data.xexp), null);
            rear = rear.next;
            p = p.next;
        }

        while (q != null) {
            if (add)
                rear.next = new Node<TermX>(new TermX(q.data.coef, p.data.xexp), null);
            else
                rear.next = new Node<TermX>(new TermX(-q.data.coef, p.data.xexp), null);
            rear = rear.next;
            q = q.next;
        }*/
        return poly;
    }


}
